package com.xhu.controller;

import com.xhu.base.MetaDataManager;
import com.xhu.base.RNDOnion;
import net.sf.jsqlparser.JSQLParserException;
import net.sf.jsqlparser.statement.delete.Delete;

import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.HashMap;
import java.util.Map;

/**
 * Delete语句解析改写
 * @author 王涛
 * @Created by WT on 2019/3/27.
 */
public class DeleteDeparser {

    public DeleteDeparser(){
    }
    public String deleteReconstruct(Delete delete, Map<String,MetaDataManager> metaOfTable) throws JSQLParserException {

        MetaDataManager metaManager = metaOfTable.values().iterator().next();
        //List<Column> columnList = new ArrayList<Column>();
        String tableName = delete.getTable().getName();
        metaManager.fetchMetaData(tableName);
        StringBuilder buffer = new StringBuilder();
        //我们需要设置一个SelectDeparser来处理select嵌套语句，不过我们不允许嵌套
        //我们把where子句的解析统一交给WhereExpressionDeparser类完成。
        WhereExpressionDeparser whereExpressionDeparser = new WhereExpressionDeparser(metaOfTable,null,buffer);
        if(delete.getWhere() != null){
            delete.getWhere().accept(whereExpressionDeparser);
        }
        return delete.toString()+";";
    }

    public static void handler(Delete delete,Connection conn){
        try {
            //Connection conn = ConnectionMySQL.openConnection();
            //Statement stmt = conn.createStatement();
            //String inputSQL = "delete from test where name = 'wang'";
            //String inputSQL = "delete from test where id > 1.0 ";
            Statement smt = conn.createStatement();
            DeleteDeparser deleteRec = new DeleteDeparser();
            String tableName = delete.getTable().getName();
            Map<String,MetaDataManager> metaOfTable = new HashMap<String,MetaDataManager>();
            MetaDataManager metaManager = new MetaDataManager();
            metaManager.fetchMetaData(tableName);
            metaOfTable.put(tableName, metaManager);
            String outputSQL = deleteRec.deleteReconstruct(delete,metaOfTable);

            if(Client.encColumnNameList.size() > 0){
                //1.如果当前where子句中需要匹配DET列，则先剥去RND层，再删除
                String peelOff = RNDOnion.peelOffRND(tableName, Client.encColumnNameList, "123456");
                smt.executeUpdate(peelOff);

                //2.下面将处理后的密文SQL语句提交给数据库执行，但是在此之前我们要剥去RND层
                smt.executeUpdate(outputSQL);

			/*3.比如我们的语句是delete from peach where id = 3;
			 * 我们把id=3的那条记录删除了，但是其他记录中的id列处在DET层，我们必须将id_DET重新加密为RND
			 */

                String packOn = RNDOnion.packOnRND(tableName, Client.encColumnNameList, "123456");
                smt.executeUpdate(packOn);
                smt.close();
            }else{
			/*如果当前没有where子句，则不需要剥去RND层。直接删除即可
			 */
                //1. 执行delete语句
                smt.executeUpdate(outputSQL);
                smt.close();
            }
        } catch (SQLException e) {
            e.printStackTrace();
        } catch (JSQLParserException e) {
            e.printStackTrace();
        }
    }
}
